{*****************************Version: MPL 1.1*********************************
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* Initial Developer : Fajar Khairil
*
* Portions created by the Initial Developer are Copyright (C) 2010 - 2011
* the Initial Developer. All Rights Reserved.
*
*******************************************************************************
* This File is Part of HadeFramework OPF Library
* Copyright (C) 2010 - 2011 HadeFramework Developer Team
*
* Unit : hadeHTTP
* Description : HadeFramework HTTP abstract Class.
* Author: - Herux
******************************************************************************}
unit hadeHTTP;

{$I ..\hddefines.inc}
{$mode objfpc}{$H+}

interface

uses
  Classes,
  SysUtils,
  hadebaseobject,
  contnrs;

resourcestring
  cErrorDuplicatedHTTPClassMap = 'Error duplicated THadeHTTP class mapping %s';
  cErrorUnregisterHTTPClassMap = 'Error unregister THadeHTTP class mapping %s';

type

  { THadeHTTP }

  THadeHTTP = class(THadeBaseObject)
  private
    FHeaders: TStringList;
    FInput: TStringStream;
    FOutput: TStringStream;
    function GetResponseHeader(const AName: string): string;
    function GetResponseHeaders: TStringList; virtual;
    procedure SetResponseHeader(const AName: string; const AValue: string);
  protected
    function GetProxyHost: string; virtual; abstract;
    function GetProxyPort: integer; virtual; abstract;
    function GetResponseCode: integer; virtual; abstract;
    function GetResponseText: string; virtual; abstract;
    procedure SetProxyHost(const AValue: string); virtual; abstract;
    procedure SetProxyPort(const AValue: integer); virtual; abstract;
  public
    class function MappingName: string; virtual; abstract;
    constructor Create; virtual;
    destructor Destroy; override;

    procedure Clear;
    procedure Post(const AURL: string);
    procedure Get(const AURL: string);
    function GetMappingName: string;

    property Input: TStringStream read FInput;
    property Output: TStringStream read FOutput;
    property ProxyHost: string read GetProxyHost write SetProxyHost;
    property ProxyPort: integer read GetProxyPort write SetProxyPort;
    property ResponseCode: integer read GetResponseCode;
    property ResponseText: string read GetResponseText;
    property ResponseHeaders: TStringList read GetResponseHeaders;
    property ResponseHeader[const AName: string]: string read GetResponseHeader write SetResponseHeader;
  end;

  THadeHTTPClass = class of THadeHTTP;

  { THadeHTTPFactory }

  THadeHTTPFactory = class(THadeBaseObject)
  private
    FList: TClassList;
    function FindMapping(const AMappingName: string): integer;
  public
    constructor Create;
    destructor Destroy; override;

    procedure RegisterMapping(const AMappingName: string; const AMappingClass: THadeHTTPClass);
    function CreateInstance(const AMappingName: string): THadeHTTP;
  end;

function HadeHTTPFactory: THadeHTTPFactory;

implementation

uses
  hadeexception
  ;

var
  AHadeHTTPFactory: THadeHTTPFactory;

function HadeHTTPFactory: THadeHTTPFactory;
begin
  if not Assigned(AHadeHTTPFactory) then
     AHadeHTTPFactory := THadeHTTPFactory.Create;
  Result := AHadeHTTPFactory;
end;

{ THadeHTTPFactory }

function THadeHTTPFactory.FindMapping(const AMappingName: string): integer;
var
  i: integer;
begin
  Result := -1;
  for i := 0 to FList.Count - 1 do
      if SameText(THadeHTTPClass(FList.Items[i]).MappingName, AMappingName) then
      begin
        Result := i;
        Exit;
      end;
end;

constructor THadeHTTPFactory.Create;
begin
  inherited;
  FList := TClassList.Create;
end;

destructor THadeHTTPFactory.Destroy;
begin
  FList.Free;
  inherited;
end;

procedure THadeHTTPFactory.RegisterMapping(const AMappingName: string;
  const AMappingClass: THadeHTTPClass);
begin
  if FindMapping(AMappingName) <> -1 then
     raise(EHadeProgrammerException.CreateFmt(cErrorDuplicatedHTTPClassMap, [AMappingName]));
  FList.Add(AMappingClass);
end;

function THadeHTTPFactory.CreateInstance(const AMappingName: string
  ): THadeHTTP;
var
  i: integer;
begin
  i := FindMapping(AMappingName);
  if i = -1 then
     raise(EHadeProgrammerException.CreateFmt(cErrorUnregisterHTTPClassMap, [AMappingName]));
  Result := THadeHTTPClass(FList.Items[i]).Create as THadeHTTP;
end;

{ THadeHTTP }

function THadeHTTP.GetResponseHeader(const AName: string): string;
begin

end;

function THadeHTTP.GetResponseHeaders: TStringList;
begin

end;

procedure THadeHTTP.SetResponseHeader(const AName: string; const AValue: string
  );
begin

end;

constructor THadeHTTP.Create;
begin
  Inherited;
  FInput := TStringStream.Create('');
  FOutput:= TStringStream.Create('');
end;

destructor THadeHTTP.Destroy;
begin
  FInput.Free;
  FOutput.Free;
  FreeAndNil(FHeaders);
  inherited;
end;

procedure THadeHTTP.Clear;
begin
  FInput.Size:= 0;
  FOutput.Size:= 0;
  FreeAndNil(FHeaders);
end;

procedure THadeHTTP.Post(const AURL: string);
begin

end;

procedure THadeHTTP.Get(const AURL: string);
begin

end;

function THadeHTTP.GetMappingName: string;
begin
  Result := THadeHTTP(ClassType).MappingName;
end;

initialization
  HadeHttpFactory();

finalization
  FreeAndNil(AHadeHTTPFactory);

end.

